home *** CD-ROM | disk | FTP | other *** search
/ Programming Microsoft Visual Basic .NET / Programming Microsoft Visual Basic .NET (Microsoft Press)(X08-78517)(2002).bin / 26 web services / advancedws / soapextensions.vb < prev    next >
Encoding:
Text File  |  2002-03-19  |  5.9 KB  |  159 lines

  1. Imports System.Web.Services
  2. Imports System.Web.Services.Protocols
  3. Imports System.Net
  4. Imports System.Threading
  5. Imports System.Web.Security
  6. Imports System.Xml.Serialization
  7. Imports System.IO
  8.  
  9. ' The custom attribute that you must use to flag methods that require 
  10. ' a given subscription level.
  11.  
  12. <AttributeUsage(AttributeTargets.Method)> _
  13. Public Class SoapCustomAuthenticationAttribute
  14.     Inherits SoapExtensionAttribute
  15.  
  16.     ' The attribute constructor
  17.     Sub New(ByVal requiredSubscriptionLevel As Integer)
  18.         Me.RequiredSubscriptionLevel = requiredSubscriptionLevel
  19.     End Sub
  20.  
  21.     ' You must override the Priority property.
  22.  
  23.     Dim m_Priority As Integer
  24.  
  25.     Public Overrides Property Priority() As Integer
  26.         Get
  27.             Return m_Priority
  28.         End Get
  29.         Set(ByVal Value As Integer)
  30.             m_Priority = Value
  31.         End Set
  32.     End Property
  33.  
  34.     ' The ExtentionType property must return the type of the SoapExtension class.
  35.  
  36.     Public Overrides ReadOnly Property ExtensionType() As System.Type
  37.         Get
  38.             Return GetType(SoapCustomAuthentication)
  39.         End Get
  40.     End Property
  41.  
  42.     ' The RequiredSubscriptionLevel property is a custom property for this attribute.
  43.  
  44.     Dim m_RequiredSubscriptionLevel As Integer
  45.  
  46.     Property RequiredSubscriptionLevel() As Integer
  47.         Get
  48.             Return m_RequiredSubscriptionLevel
  49.         End Get
  50.         Set(ByVal Value As Integer)
  51.             m_RequiredSubscriptionLevel = Value
  52.         End Set
  53.     End Property
  54. End Class
  55.  
  56. ' The Soap extension class.
  57.  
  58. Class SoapCustomAuthentication
  59.     Inherits SoapExtension
  60.  
  61.     ' When the SoapExtension class is instantiated, the GetInitializer method is called.
  62.     ' This method receives a reference to the custom attribute that flagged the method.
  63.     ' The value returned by GetInitializer is then passed to the Initialize method each 
  64.  
  65.     ' This overloads of the GetInitializer method is called if the Soap extension is
  66.     ' installed in web.config and receives the Type of the WebService class.
  67.  
  68.     Public Overloads Overrides Function GetInitializer(ByVal serviceType As System.Type) As Object
  69.         ' In this case we just return 1 - the lowest subscription level necessary to 
  70.         ' access methods in the Web Service
  71.         If serviceType Is GetType(SoapCustomAuthentication) Then
  72.             Return 1
  73.         End If
  74.     End Function
  75.  
  76.     ' This overloads of the GetInitializer method is called if the Soap extension is
  77.     ' installed because a method was flagged with a SoapExtensionAttribute
  78.     ' and receives the attribute in the second argument.
  79.  
  80.     Public Overloads Overrides Function GetInitializer(ByVal methodInfo As System.Web.Services.Protocols.LogicalMethodInfo, ByVal attribute As System.Web.Services.Protocols.SoapExtensionAttribute) As Object
  81.         ' Get a reference to the attribute.
  82.         Dim scaAttr As SoapCustomAuthenticationAttribute = DirectCast(attribute, SoapCustomAuthenticationAttribute)
  83.         ' Return its RequiredSubscriptionLevel property.
  84.         Return scaAttr.RequiredSubscriptionLevel
  85.     End Function
  86.  
  87.     ' The Initialize method is called with the RequiredSubscriptionLevel integer
  88.     ' in its argument.
  89.  
  90.     Dim RequiredSubscriptionLevel As Integer
  91.  
  92.     Public Overrides Sub Initialize(ByVal initializer As Object)
  93.         ' Save the required subscription level for later.
  94.         RequiredSubscriptionLevel = CInt(initializer)
  95.     End Sub
  96.  
  97.     Dim oldStream As Stream
  98.     Dim newStream As Stream
  99.  
  100.     ' The ChainStream is called when the SoapExtension class is instantiated.
  101.  
  102.     Public Overrides Function ChainStream(ByVal stream As Stream) As Stream
  103.         ' Save the old stream.
  104.         oldStream = stream
  105.         ' Create a new stream and return it.
  106.         newStream = New MemoryStream()
  107.         Return newStream
  108.     End Function
  109.  
  110.     ' a reusable routine used by most SOAP extensions 
  111.  
  112.     Private Sub CopyStream(ByVal source As Stream, ByVal dest As Stream, Optional ByVal resetSource As Boolean = True)
  113.         Dim sr As New StreamReader(source)
  114.         Dim sw As New StreamWriter(dest)
  115.         sw.WriteLine(sr.ReadToEnd)
  116.         sw.Flush()
  117.     End Sub
  118.  
  119.     ' This method is called multiple times for each message.
  120.     Public Overrides Sub ProcessMessage(ByVal message As System.Web.Services.Protocols.SoapMessage)
  121.  
  122.         Select Case message.Stage
  123.             Case SoapMessageStage.BeforeDeserialize
  124.                 CopyStream(oldStream, newStream)
  125.                 newStream.Position = 0
  126.  
  127.             Case SoapMessageStage.AfterDeserialize
  128.                 ' The message has been deserialized, so we can access the headers collection.
  129.                 If EvalSubscriptionLevel(message) < RequiredSubscriptionLevel Then
  130.                     ' Throw an exception if subscription level isn't adequate.
  131.                     Throw New SoapException("Invalid account or insufficient subscription level", SoapException.ClientFaultCode)
  132.                 End If
  133.             Case SoapMessageStage.BeforeSerialize
  134.             Case SoapMessageStage.AfterSerialize
  135.                 newStream.Position = 0
  136.                 CopyStream(newStream, oldStream)
  137.         End Select
  138.     End Sub
  139.  
  140.     Private Function EvalSubscriptionLevel(ByVal message As SoapMessage) As Integer
  141.         ' Check whether there is a header of type AccountInfoHeader 
  142.         Dim header As SoapHeader
  143.         For Each header In message.Headers
  144.             If TypeOf header Is AccountInfoHeader Then
  145.                 ' cast to the propert type
  146.                 Dim accountInfo As AccountInfoHeader = DirectCast(header, AccountInfoHeader)
  147.                 ' Check user credentials and return subscription level.
  148.                 Return GetUserSubscriptionLevel(accountInfo.UserName, accountInfo.Password)
  149.             End If
  150.         Next
  151.  
  152.         ' If we get here, credentials were missing or invalid.
  153.         Return -1
  154.     End Function
  155.  
  156.  
  157. End Class
  158.  
  159.